package net.didactylos.helpline.data;

import java.nio.*;
import java.nio.charset.*;
import java.security.*;
import java.util.*;

import javax.persistence.*;

import net.didactylos.helpline.servlet.Base64;

@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "username" }))
public class User extends EmailContact
{
	public static User NOBODY;
	
	static
	{
		NOBODY = new User();
		NOBODY.role = new Role();
	}

	@Column(length=50)
	private String username;
	
	@ManyToOne
	private Role role;
	
	@Column(length=32)
	private byte[] passwordHash;

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public Role getRole()
	{
		return role;
	}

	public void setRole(Role role)
	{
		this.role = role;
	}
	
	public void setPassword(String password)
	{
		passwordHash = generateHash(password);
	}
	
	public boolean hasCapability(long capability)
	{
		return (role.getCapabilities() & capability) == capability;
	}

	public boolean verifyPassword(String password)
	{
		byte[] hash = generateHash(password);
			
		return Arrays.equals(hash, passwordHash);
	}
	
	private byte[] generateHash(String password)
	{
		// TODO: replace with service name.
		String hashBase = "Guide-Line" + username + password;
		CharsetEncoder enc = Charset.forName("UTF-8").newEncoder();
		try
		{
			ByteBuffer bytes = enc.encode(CharBuffer.wrap(hashBase));
			MessageDigest sha = MessageDigest.getInstance("SHA-256");
			byte[] hash = sha.digest(bytes.array());
			
			return hash;
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public String generatePassword(int length)
	{
		// Quick hack to turn random bytes into characters.
		SecureRandom random;
		try
		{
			random = SecureRandom.getInstance("SHA1PRNG");
			byte[] rawBytes = new byte[(int)((double)length * 0.75) + 2];
			random.nextBytes(rawBytes);
			String s = Base64.encodeBytes(rawBytes);
	
			String password = s.substring(0, length);
			setPassword(password);
			return password;
		}
		catch (NoSuchAlgorithmException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
